package org.wheel.plugins.toolkit.sql.segment;

import cn.hutool.core.util.StrUtil;
import org.wheel.plugins.toolkit.sql.core.AbstractWrapper;
import org.wheel.plugins.toolkit.sql.core.SqlSegment;
import org.wheel.plugins.toolkit.sql.helper.ColumnRef;
import org.wheel.plugins.toolkit.sql.helper.FieldMeta;

import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;


/**
 * 自动展开 VO 字段
 */
public final class SelectBuilder {

    /* 缓存 VO 元数据 */
    private static final Map<Class<?>, List<FieldMeta>> META_CACHE = new ConcurrentHashMap<>();

    /* 返回 SelectSegment[]：t2.column AS collectionField.voField */
    public static <T, W extends AbstractWrapper<T, W>> ColumnRef[] collection(String tableAlias,
                                         String collectionField,
                                         Class<?> voClass,
                                         AbstractWrapper<T, W> wrapper) {
        List<FieldMeta> list = META_CACHE.computeIfAbsent(voClass, k ->
                Arrays.stream(k.getDeclaredFields())
                        .filter(f -> !Modifier.isStatic(f.getModifiers()))
                        .map(FieldMeta::new)
                        .collect(Collectors.toList()));
        return list.stream().map(f-> {
            ColumnRef ref = ColumnRef.of(tableAlias, f.getColumn(),
                    "\""+collectionField + "." + f.getFieldName() +"\"", wrapper);
            if(StrUtil.isBlank(tableAlias)){
                ref.setTableEntityClass(voClass);
            }
            return ref;
        }).toArray(ColumnRef[]::new);
    }

    /**
     * 把 SelectSegment[] 拼成一条 "t2.a AS af, t2.b AS bf, ..."
     */
    public static SelectSegment join(ColumnRef[] arr) {
        return () -> Arrays.stream(arr)
                .map(SqlSegment::getSql)
                .collect(Collectors.joining(", "));
    }
}
